package org.redmagic.agent.location.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.annotation.Nonnull;

import org.redmagic.ResponseDecoder;
import org.redmagic.TransactionManager;
import org.redmagic.agent.location.DomLocationParser;
import org.redmagic.location.UriLocation;
import org.redmagic.location.web.BulkTransactionManager;
import org.redmagic.location.web.JsonResponseDecoder;
import org.redmagic.utils.Conditions;
import org.redmagic.utils.Documents;
import org.w3c.dom.Element;

public class WebLocationParser implements DomLocationParser {

    private static final String ATTEMPT = "attempt";

    private final TransactionManager transactionManager;

    public WebLocationParser() {
    	ResponseDecoder jsonDecoder = new JsonResponseDecoder();
		Map<String, ResponseDecoder> responseDecoders = new HashMap<String, ResponseDecoder>();
		responseDecoders.put(jsonDecoder.getMediaType(), jsonDecoder);
		transactionManager = new BulkTransactionManager(responseDecoders);
    }
    
    public WebLocationParser(TransactionManager transactionManager) {
        this.transactionManager = Conditions.notNull(transactionManager, "transactionManager");
    }

    @Override
    public UriLocation parse(Element locationElement) {
        List<List<String>> hierarchy = new ArrayList<List<String>>();
        
        
        Iterable<Element> attempts = Documents.getElementsByTag(locationElement, ATTEMPT);
        Iterator<Element> iter = attempts.iterator();
        while (iter.hasNext()) {
            hierarchy.add(parseAttemptForTags(iter.next()));
        }
        String uri = locationElement.getAttribute("uri");
        return new WebLocation(uri, hierarchy, transactionManager);
    }

    @Nonnull
    private List<String> parseAttemptForTags(Element attempt) {

        SortedSet<String> tags = new TreeSet<String>();

        if (attempt.hasChildNodes()) {
            Iterable<Element> tagsList = Documents.getElementsByTag(attempt, "tag");
            Iterator<Element> iter = tagsList.iterator();
            while (iter.hasNext()) {
                Element tag = iter.next();
                tags.add(tag.getTextContent().trim());
            }
        }

        return new ArrayList<String>(tags);
    }
}
